<!--
 * @Author: huangwei
 * @Date: 2021-05-13 11:22:40
 * @LastEditors: 黄威
 * @LastEditTime: 2022-02-17 15:27:28
 * @Description: 卷帘工具
-->
<template>
    <div class="mgs-view-compare">
        <MgsLMap
            link-move
            :view.sync="currentView"
            :options="options"
            :style="firstStyle"
            @onMapInited="initEndHandler($event)"
        />
        <MgsLMap
            link-move
            :view.sync="currentView"
            :options="options"
            :style="secondStyle"
            @onMapInited="initEndHandler($event, true)"
        />
        <div
            class="sbs-divider"
            :class="{ horizontal }"
            data-transfer="true"
            style="will-change: top, left"
            :style="{ [horizontal ? 'top' : 'left']: percent * 100 + '%' }"
        >
            <span class="sbs-range" @mousedown="changeHandler" />
        </div>
    </div>
</template>

<script lang="ts">
import type { View } from 'types'
import { Component, Prop, Watch, Vue } from 'vue-property-decorator'

import MgsLMap from '../MgsLMap'
import L from 'leaflet'

@Component({ components: { MgsLMap } })
export default class MgsViewCompare extends Vue {
    /**
     * 地图初始化参数（详细请看 `L.MapOptions`）
     */
    @Prop({ type: Object, default: () => ({}) })
    options!: L.MapOptions

    /**
     * 图幅中心点和缩放（支持sync参数）
     */
    @Prop({
        type: Object,
        default: () => ({
            center: [0, 0],
            zoom: 1,
        }),
    })
    view!: View

    /**
     * 是否为上下模式，默认fasle
     */
    @Prop({ type: Boolean, default: false })
    horizontal!: boolean

    currentView?: View = this.view

    // 视图宽高
    width = 0
    height = 0

    // 卷帘百分比
    percent = 0.5

    // 地图
    firstMap: MgsLMap | null = null
    secondMap: MgsLMap | null = null

    // 第一个地图样式
    get firstStyle(): any {
        if (this.firstMap && this.secondMap) {
            // 左右分屏
            if (!this.horizontal)
                return {
                    clip: `rect(
                        0,
                        ${this.width * this.percent}px,
                        ${this.height}px,
                        0
                    )`,
                }
            // 上下分屏
            else
                return {
                    clip: `rect(
                        0,
                        ${this.width}px,
                        ${this.height * this.percent}px,
                        0
                    )`,
                }
        }
        return {}
    }

    // 第二个地图地图样式
    get secondStyle(): any {
        if (this.firstMap && this.secondMap) {
            // 左右分屏
            if (!this.horizontal)
                return {
                    clip: `rect(
                        0,
                        ${this.width}px,
                        ${this.height}px,
                        ${this.width * this.percent}px
                    )`,
                }
            // 上下分屏
            else
                return {
                    clip: `rect(
                        ${this.height * this.percent}px,
                        ${this.width}px,
                        ${this.height}px,
                        0
                    )`,
                }
        }
        return {}
    }

    @Watch('view')
    viewWatcher(nvl: View) {
        this.currentView = nvl
    }

    @Watch('currentView')
    currentViewWatcher(nvl: View) {
        this.$emit('update:view', nvl)
    }

    initEndHandler(bindMap: MgsLMap, isSecond: boolean = false) {
        this[!isSecond ? 'firstMap' : 'secondMap'] = bindMap

        // 如果地图初始化完毕
        if (this.firstMap && this.secondMap) {
            this.resize()
            this.secondMap.map.on('resize', () => this.resize())

            /**
             * 初始化完毕
             * @property {MgsLMap} firstMap 第一个地图对象
             * @property {MgsLMap} secondMap 第二个地图对象
             */
            this.$emit('onInited', this.firstMap, this.secondMap)
        }
    }

    resize() {
        const { width, height } = getComputedStyle(this.$el)
        this.width = parseFloat(width)
        this.height = parseFloat(height)
    }

    changeHandler(evt: MouseEvent) {
        let lastX = evt.x
        let lastY = evt.y

        const moveHandler = (evt: MouseEvent) => {
            const { x, y } = evt

            let offsetPerc = 0
            if (!this.horizontal) {
                offsetPerc = (x - lastX) / this.width
            } else {
                offsetPerc = (y - lastY) / this.height
            }

            this.percent = Math.min(Math.max(0, this.percent + offsetPerc), 1)

            lastX = x
            lastY = y
        }
        const clearHandler = () => {
            document.removeEventListener('mousemove', moveHandler)
            document.removeEventListener('mouseup', clearHandler)
        }
        document.addEventListener('mousemove', moveHandler)
        document.addEventListener('mouseup', clearHandler)
    }
}
</script>

<docs>
## Demo

::: demo

<template>
    <mgs-view-compare
        style="height: 500px; width: 100%;"
        :options="options"
        :horizontal="horizontal"
        @onInited="initEndHandler"
    />
</template>

<script>
export default {
    data() {
        return {
            options: {
                preferCanvas: true,
                crs: L.CRS.EPSG3857,
            },
            horizontal: false,
            oneMap: null,
            secMap: null,
        };
    },
    methods: {
        initEndHandler(oneMap, secMap) {
            this.oneMap = oneMap;
            this.secMap = secMap;

            oneMap.addService(
                '1',
                'arcgisrestmap',
                'https://server.arcgisonline.com/arcgis/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer'
            )

            secMap.addService(
                '1',
                'arcgisrestmap',
                'https://server.arcgisonline.com/arcgis/rest/services/Specialty/DeLorme_World_Base_Map/MapServer'
            )
        },
    }
}
</script>

:::
</docs>
